import 'dart:async';

import 'package:animated_widgets/widgets/rotation_animated.dart';
import 'package:animated_widgets/widgets/shake_animated_widget.dart';
import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:flutterzhuyili/bean/sqlBean.dart';
import 'package:flutterzhuyili/model/sqlModel.dart';
import 'package:intl/intl.dart';

///@author xuziqiang
/// @date 2020/8/5 15:28
///

class MyGridView extends StatefulWidget {
  MyGridView(
      {Key key,
      this.rows = 3,
      this.columns = 3,
      this.isPoem = false,
      this.backgroundColors,
      this.backgroundTextStyle,
      this.singleBackgroundColor = Colors.transparent,
      this.singleTextStyle,
      this.isChildMode = false,
      this.canErrorTimes = 3,
      this.isRandomMode = false,
      this.childModeTextStyle,
      this.data})
      : super(key: key);

  final int rows;
  final int columns;
  final List<Color> backgroundColors;
  final TextStyle singleTextStyle;
  final Color singleBackgroundColor;
  final TextStyle backgroundTextStyle;
  final List<String> data;
  final bool isChildMode; //点完正确的之后 降低对比度
  final int canErrorTimes; //可以点击错误的次数
  final bool isRandomMode; //每次数字都会重新排序
  final TextStyle childModeTextStyle;
  final bool isPoem;

  @override
  _MyGridViewState createState() => _MyGridViewState(
      rows,
      columns,
      backgroundColors,
      singleTextStyle,
      singleBackgroundColor,
      backgroundTextStyle,
      data,
      isChildMode,
      canErrorTimes,
      isRandomMode,
      childModeTextStyle,
      isPoem);
}

class _MyGridViewState extends State<MyGridView> {
  _MyGridViewState(
      this._rows,
      this._columns,
      this._backgroundColors,
      this._singleTextStyle,
      this._singleBackgroundColor,
      this._backgroundTextStyle,
      this._data,
      this._isChildMode,
      this._canErrorTimes,
      this._randomStr,
      this._childModeTextStyle,
      this._isPoem);

  int _rows;
  int _columns;
  List<Color> _backgroundColors;
  TextStyle _singleTextStyle;
  Color _singleBackgroundColor;
  TextStyle _backgroundTextStyle;
  List<String> _data;
  bool _isChildMode;
  int _canErrorTimes = 3;
  int _hadErrorTimes = 0; //已经错误的次数
  bool _randomStr;
  TextStyle _childModeTextStyle;

  List<String> hadRightList = List();
  int gameStartTime = DateTime.now().millisecondsSinceEpoch;
  int clickFirstTime;
  int clickSecondTime;
  int clickLastTime;

  String nextTrueStr;
  RadioControlModel model = RadioControlModel();
  bool _shakeEnable = false;
  List<bool> _shakeList = List();
  String _backgroundStr = '';
  int _theBestWholeTime = 0;
  int _wholeTime = 0;
  int _theBestHandTime = 0;
  int _handTime = 0;
  int _theBestResponseTime = 0;
  int _responseTime = 0;
  bool _isPoem = false;

  bool isFinish = false;

  int _mode = 0;

  Timer _timer;
  int time = 0;

  @override
  void initState() {
    super.initState();
    init();
  }

  init(){
    if (_isChildMode) {
      _mode = _mode + 1;
    }
    if (_canErrorTimes == 0) {
      _mode = _mode + 2;
    }
    if (_randomStr) {
      _mode = _mode + 4;
    }
    initBestRecord();
    const tenMs = const Duration(milliseconds: 100);
    var callback = (timer) => {
      setState(() {
        time = time + 100;
      })
    };

    _timer = Timer.periodic(tenMs, callback);
  }

  _reStart() {
    _timer.cancel();
    time = 0;
    _hadErrorTimes = 0;
    hadRightList.clear();
    nextTrueStr = null;
    _shakeList.clear();
    _mode = 0;
    isFinish = false;
    _handTime = 0;
    _responseTime = 0;
    init();
  }

  _showTryAgainDialog(String str) {
    AwesomeDialog(
      dismissOnTouchOutside: false,
      context: context,
      animType: AnimType.TOPSLIDE,
      dialogType: DialogType.SUCCES,
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text('$str'),
          Text('是否继续挑战？'),
        ],
      ),
      btnCancelText: '返回',
      btnCancelOnPress: () {
        Navigator.pop(context);
      },
      btnOkText: '继续',
      btnOkOnPress: () async {
        _reStart();
      },
    )..show();
  }

  _showErrorDialog(String str) {
    _timer.cancel();
    AwesomeDialog(
      dismissOnTouchOutside: false,
      context: context,
      animType: AnimType.TOPSLIDE,
      dialogType: DialogType.ERROR,
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text('$str'),
          Text('是否继续挑战？'),
        ],
      ),
      btnCancelText: '返回',
      btnCancelOnPress: () {
        Navigator.pop(context);
      },
      btnOkText: '继续',
      btnOkOnPress: () async {
        _reStart();
      },
    )..show();
  }

  @override
  void dispose() {
    super.dispose();
    if (_timer != null) {
      _timer.cancel();
    }
  }

  initBestRecord() async {
    int hand = await model.getBestHandTime(_rows, _columns, _mode);
    int whole = await model.getBestWholeTime(_rows, _columns, _mode);
    int response = await model.getBestResponseTime(_rows, _columns, _mode);
    setState(() {
      _theBestWholeTime = whole;
      _theBestResponseTime = response;
      _theBestHandTime = hand;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_shakeList.isEmpty) {
      _data = widget.data.sublist(0); //深拷贝
      nextTrueStr = _data[0];
      _data.shuffle();
      _data.forEach((element) {
        _shakeList.add(false);
      });
    }

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(left: 10, right: 10),
              child: Container(
                height: 150,
                child: _isPoem
                    ? MediaQuery.removePadding(
                        removeTop: true,
                        context: context,
                        child: GridView.count(
                          physics: NeverScrollableScrollPhysics(),
                          crossAxisCount: 2,
                          childAspectRatio: 6,
                          crossAxisSpacing: 10,
                          mainAxisSpacing: 10,
                          children: <Widget>[
                            Text(''),
                            Text(
                              '当前',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '耗时',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${(time / 1000).toStringAsFixed(2)} s',
                              style: TextStyle(
                                  fontSize: 28, fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '手速',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_handTime != 0 ? '${(_handTime / 1000).toStringAsFixed(2)}s' : '***'} ',
                              style: TextStyle(
                                  fontSize: 28, fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '反应',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_responseTime != 0 ? '${(_responseTime / 1000).toStringAsFixed(2)}s' : '***'}',
                              style: TextStyle(
                                  fontSize: 28, fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                          ],
                        ),
                      )
                    : MediaQuery.removePadding(
                        removeTop: true,
                        context: context,
                        child: GridView.count(
                          physics: NeverScrollableScrollPhysics(),
                          crossAxisCount: 3,
                          childAspectRatio: 4,
                          crossAxisSpacing: 10,
                          mainAxisSpacing: 10,
                          children: <Widget>[
                            Text(''),
                            Text(
                              '历史最优',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '当前',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '耗时',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_theBestWholeTime == 0 ? '*****' : (_theBestWholeTime / 1000).toStringAsFixed(2)} s',
                              style: TextStyle(
                                  fontSize: 28, fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${(time / 1000).toStringAsFixed(2)} s',
                              style: TextStyle(
                                  color: _theBestWholeTime > time ||
                                          _theBestWholeTime == 0
                                      ? Colors.green
                                      : null,
                                  fontSize: 28,
                                  fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '手速',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_theBestHandTime == 0 ? '*****' : (_theBestHandTime / 1000).toStringAsFixed(2)} s',
                              style: TextStyle(
                                  fontSize: 28, fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_handTime != 0 ? (_handTime / 1000).toStringAsFixed(2) : '**'} s',
                              style: TextStyle(
                                  color: _theBestHandTime > _handTime ||
                                          _theBestWholeTime == 0
                                      ? Colors.green
                                      : null,
                                  fontSize: 28,
                                  fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '反应',
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_theBestResponseTime == 0 ? '*****' : (_theBestResponseTime / 1000).toStringAsFixed(2)} s',
                              style: TextStyle(
                                  fontSize: 28, fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                            Text(
                              '${_responseTime != 0 ? (_responseTime / 1000).toStringAsFixed(2) : '**'} s',
                              style: TextStyle(
                                  color: _theBestResponseTime > _responseTime ||
                                          _theBestResponseTime == 0
                                      ? Colors.green
                                      : null,
                                  fontSize: 28,
                                  fontStyle: FontStyle.italic),
                              textAlign: TextAlign.center,
                            ),
                          ],
                        ),
                      ),
              ),
            ),
            Container(
              width: double.infinity,
              decoration: _backgroundColors != null
                  ? BoxDecoration(
                      gradient: LinearGradient(
                          begin: Alignment.centerLeft,
                          end: Alignment.bottomCenter,
                          colors: widget.backgroundColors),
                    )
                  : BoxDecoration(),
              child: AspectRatio(
                aspectRatio: _rows / _columns,
                child: Stack(
                  children: <Widget>[
                    ShakeAnimatedWidget(
                      enabled: _shakeEnable,
                      duration: Duration(milliseconds: 200),
                      shakeAngle: Rotation.deg(z: 10),
                      curve: Curves.linear,
                      child: Center(
                        child: Text(
                          _backgroundStr,
                          style: _backgroundTextStyle,
                        ),
                      ),
                    ),
                    MediaQuery.removePadding(
                      removeTop: true,
                      context: context,
                      child: GridView.builder(
                          physics: NeverScrollableScrollPhysics(),
                          itemCount: _data.length,
                          //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
                          gridDelegate:
                              SliverGridDelegateWithFixedCrossAxisCount(
                                  //横轴元素个数
                                  crossAxisCount: _rows,
                                  //纵轴间距
                                  mainAxisSpacing: 3.0,
                                  //横轴间距
                                  crossAxisSpacing: 3.0,
                                  //子组件宽高长度比例
                                  childAspectRatio: 1.0),
                          itemBuilder: (BuildContext context, int index) {
                            //Widget Function(BuildContext context, int index)
                            return GestureDetector(
                              onTap: () {
                                clickListener(index);
                              },
                              child: Container(
                                  color: _singleBackgroundColor,
                                  child: Center(
                                    child: ShakeAnimatedWidget(
                                      enabled: _shakeList[index],
                                      duration: Duration(milliseconds: 200),
                                      shakeAngle: Rotation.deg(z: 10),
                                      curve: Curves.linear,
                                      child: Text(
                                        _data[index],
                                        style: isUseChildModeStyle(index)
                                            ? _childModeTextStyle
                                            : _singleTextStyle,
                                      ),
                                    ),
                                  )),
                            );
                          }),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  String getNextTrueStr(String nowStr) {
    if (widget.data.last == nowStr) return null;
    return widget.data[widget.data.indexOf(nowStr) + 1];
  }

  isUseChildModeStyle(int index) {
    if (!_isChildMode) return false;
    if (hadRightList.contains(_data[index]) && _childModeTextStyle != null)
      return true;
    return false;
  }

  void clickListener(int index) {
    if (isFinish) return;

    setState(() {
      if (hadRightList.length == 0) {
        clickFirstTime = DateTime.now().millisecondsSinceEpoch;
        _handTime = clickFirstTime - gameStartTime;
      }
      if (hadRightList.length == 1) {
        clickSecondTime = DateTime.now().millisecondsSinceEpoch;
      }
      _backgroundStr = '';
      //这事对了
      if (nextTrueStr == _data[index]) {
        Vibrate.feedback(FeedbackType.success);
        nextTrueStr = getNextTrueStr(_data[index]);
        if (nextTrueStr == null) {
          //结束
          _gameSuccessFinish();
          return;
        }
        hadRightList.add(_data[index]);
        if (_randomStr) {
          _data.shuffle();
        }
        return;
      } else {
        //这事点错的
        Vibrate.feedback(FeedbackType.warning);
        _hadErrorTimes++;
        if (_hadErrorTimes > _canErrorTimes) {
          //游戏结束~~~~
          _showErrorDialog('挑战失败!');
          return;
        }
        if (!_shakeEnable) {
          _shakeList[index] = true;
          _shakeEnable = true;
          _backgroundStr = widget.data[hadRightList.length];
          Future.delayed(Duration(milliseconds: 500), () {
            setState(() {
              _shakeEnable = false;
              _shakeList[index] = false;
            });
          });
        }
      }
    });
  }

  _gameSuccessFinish() {
    clickLastTime = DateTime.now().millisecondsSinceEpoch;
    //要记录数据
    if (_timer != null) {
      _timer.cancel();
    }
    setState(() {
      _responseTime = (clickLastTime - clickSecondTime) ~/ (_data.length - 1);
    });
    int wholeTime = clickLastTime - gameStartTime;
    String date = DateFormat("yyyy-MM-dd").format(DateTime.now());
    isFinish = true;
    _showTryAgainDialog('恭喜成功完成。');
    if (_isPoem) {
      return;
    }
    TrainRecordEntity entity = TrainRecordEntity(
        _responseTime, _handTime, wholeTime, _rows, _columns, _mode, date);
    model.insertRecord(entity);
  }
}
